# -*- coding: utf-8 -*-
import requests
import json
import time
import datetime
from  apscheduler.schedulers.blocking import BlockingScheduler
from chinese_calendar import is_holiday, is_workday, get_holiday_detail

Authorization='MjMzNDZhMGEtY2JlZS00YWVkLTljYzYtNmE2ZGQwNzdlYjVhLDE2NDEyNzk5MzA3MTAsMGVPRzNFUjR4MWs2OXlKRlk2NGxVYi9XckQ4PQ=='

requests.packages.urllib3.disable_warnings()

class ChineseCalendar():
    '''
    入参：
        datetime.date对象

    functions:
        isHoliday
        isWorkday
        isHoliday,Holidayname = get_holiday_detail
    '''
    def __init__(self, date):
        self.april_last = datetime.date(date.year,date.month,date.day)

    def isHoliday(self):
        return is_holiday(self.april_last)

    def isWorkday(self):
        return is_workday(self.april_last)

    def get_holiday_detail(self):
        return get_holiday_detail(self.april_last)

#将信息发给手机
#https://sct.ftqq.com/sendkey
def send(messagecontent, messagetitle = '预约'):
    resp = requests.post('https://sctapi.ftqq.com/' + \
            'SCT102313T9Cde9vhpyhCEKtVQYVqbShZL' + \
            '.send?title=' + messagetitle + '&desp=' + messagecontent)

class Appoint():
    '''
    function: once_ok
    '''
    def __init__(self):
        self.headers = {
            'Host': 'webapi.mybti.cn',
            #'Connection': 'keep-alive',
            'Connection': 'close',
            #'Content-Length': '150',
            'Accept': 'application/json, text/plain, */*',
            'Origin': 'https://webui.mybti.cn',
            'Authorization':Authorization,
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) \
                AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
            'Content-Type':'application/json;charset=UTF-8',
            'Referer': 'https://webui.mybti.cn/?rd=12251331/',
            'Accept-Encoding': 'gzip, deflate, br',
            'Accept-Language': 'zh-CN,zh;q=0.9'
            }
        self.URL = 'https://webapi.mybti.cn'

    #输入日期和时间,需要和页面上存在的一致
    #入参：
    #   enterDate 预约日期
    #   timeSlot  预约时间段，默认0800-0810
    #返回
    #   状态码，0成功 1失败
    #   回应，Response结构
    def once_ok(self, enterDate, timeSlot="0810-0820" ):
        c = ChineseCalendar(enterDate)
        if c.isWorkday() is not True:
            return True,None

        body = {"lineName":"昌平线",
            "snapshotWeekOffset":0,
            "stationName":"沙河站",
            "enterDate":enterDate.strftime("%Y%m%d"),
            "snapshotTimeSlot":"0630-0930",
            "timeSlot":timeSlot}
        try:
            t0 = time.perf_counter()
            resp = requests.post(self.URL + '/Appointment/CreateAppointment', \
                    headers=self.headers,data=json.dumps(body))
            print(datetime.datetime.now(), "：doing... 耗时", time.perf_counter() - t0,
                "返回", resp.status_code, resp.text) #debug
            if resp.status_code == 200 and json.loads(resp.text).get('appointmentId') != None:
                return True,resp
        except requests.exceptions.HTTPError as ex:
            print(ex)
        return  False,None

    def get_info(self):
        resp = requests.get(self.URL + '/AppointmentRecord/GetAppointmentList?status=0&lastid=',
                headers = self.headers, verify=False)
        return resp.text

#执行次数和间隔
def job(timer = 120, interval=0.7):
    ap = Appoint()
    while timer>0:
        print(timer)
        tomorrow = (datetime.date.today()+datetime.timedelta(days=1))
        ok,resp = ap.once_ok(tomorrow)
        if ok:
            if resp == None:
                print("today is holiday, not appoint,  enjoy your time")
                return
            print("已预约成功！！！ ",resp.text)
            send(messagecontent=ap.get_info())
            return
        time.sleep(interval)
        timer = timer-1

#先检查系统时间再设置触发时间
#12、20点抢票
if __name__ == '__main__':
    sched = BlockingScheduler()
    sched.add_job(job, 'cron', day_of_week='*', hour=17, minute='58', second='59')

    try:
        sched.start()
        print("成功")
    except Exception as e:
        sched.shutdown()
        print('定时任务执行失败')
    finally:
        print("结束")
